#include "include.h"
#include "iis_audio_in.h"

#if I2S_RX_AUDIO_EN

#define  IIS_SOFT_RESAMPLES_EN      1
#define IIS_DMA_SAMPLES   120
#define IIS_DMABUF_LEN     (IIS_DMA_SAMPLES * 2 * 2 *4)  //tx,rx double_buf, one_sample_4byte

u8 iis_dmabuf[IIS_DMABUF_LEN]AT(.iis_buf);   //若iis_cfg.mode中有RAMTX或RAMRX,需要该dmabuf做中断缓存
iis_cfg_t iis_cfg;

#define IIS_RX_CIRBUF_SIZE  4096
static iis_rx_cfg_t iis_rx_cfg;
static volatile uint8_t iis_mic_in_init_flag = 0;
uint8_t iis_rx_pool[IIS_RX_CIRBUF_SIZE] AT(.iis_buf);
uint8_t iis_rx_pool_out[1024] AT(.iis_buf);

volatile u8 resample_flg = 0;

AT(.com_text.iis_ext)
void iis_rx_input_pool(u8 *ptr, u32 samples, int ch_mode, void *params)
{
    cbuf_cfg_t *src_cbuf_t = &iis_rx_cfg.iis_rx_cbuf;
    if (iis_mic_in_init_flag && (!iis_rx_cfg.mute) &&(wireless_cb.alg_en)) {
        #if IIS_SOFT_RESAMPLES_EN
        if(resample_flg == 1){//++
            cbuf_input_audio((u8 *)ptr, 4, src_cbuf_t);
            cbuf_input_audio((u8 *)ptr, samples, src_cbuf_t);
        }else if(resample_flg == 2){//--
            cbuf_input_audio((u8 *)ptr, samples-4, src_cbuf_t);
        }else
        #endif // IIS_SOFT_RESAMPLES_EN
        {//none
            cbuf_input_audio((u8 *)ptr, samples, src_cbuf_t);
        }
    }
}
AT(.com_text.iis_ext)
u32 cbuf_total_samples_get_user_for_softsrc(void)
{
    cbuf_cfg_t *src_cbuf_t = &iis_rx_cfg.iis_rx_cbuf;
    return cbuf_total_samples_get(src_cbuf_t);
}
AT(.com_text.iis_ext)
void iis_rx_callback_process(void)
{
    u16 *ptr16 = (u16*)iis_rx_pool_out;
    u32 *ptr32 = (u32*)iis_rx_pool_out;

    cbuf_cfg_t *src_cbuf_t = &iis_rx_cfg.iis_rx_cbuf;
    if(cbuf_total_samples_get(src_cbuf_t)>= WIRELESS_MIC_SAMPLES_SELECT*4){
        cbuf_output_audio((u8 *)iis_rx_pool_out, WIRELESS_MIC_SAMPLES_SELECT*4, src_cbuf_t);
        if (iis_cfg.bit_mode == IIS_32BIT) {  //IIS_32BIT
            for (int i = 0; i < WIRELESS_MIC_SAMPLES_SELECT*2; i++) {  //32BIT ->16bit  for dac out
               ptr16[2*i] =  (u16)(ptr32[2*i] >> 16);
               ptr16[2*i+1] =  (u16)(ptr32[2*i+1] >> 16);
            }
        }
        for(int j = 0;j < WIRELESS_MIC_SAMPLES_SELECT; j++)
        {
            // stereo to mono
            ptr16[j] = ptr16[j*2];
        }
        void mic_enc_audio_input(u8 *pcm, u32 samples, int ch_mode, void *params);
        mic_enc_audio_input((u8*)iis_rx_pool_out,WIRELESS_MIC_SAMPLES_SELECT,0,NULL);
    }else{
        memset(iis_rx_pool_out,0,WIRELESS_MIC_SAMPLES_SELECT*2);
        void mic_enc_audio_input(u8 *pcm, u32 samples, int ch_mode, void *params);
        mic_enc_audio_input((u8*)iis_rx_pool_out,WIRELESS_MIC_SAMPLES_SELECT,0,NULL);
    }
}

AT(.text.iis_ext)
void iis_rx_pool_init(u8 sample_rate, u16 samples)
{
    iis_mic_in_init_flag = 1;
    memset(&iis_rx_cfg, 0, sizeof(iis_rx_cfg));
    memset(&iis_rx_pool, 0, sizeof(iis_rx_pool));
    cbuf_init(&(iis_rx_cfg.iis_rx_cbuf), iis_rx_pool, IIS_RX_CIRBUF_SIZE);
}

AT(.com_text.iis_ext)
void iis_soft_isr_process(void)
{
    if (iis_rx_cfg.soft_isr_kick_flag) {
        iis_rx_cfg.soft_isr_kick_flag = 0;
#if IIS_SOFT_RESAMPLES_EN
        if(cbuf_total_samples_get_user_for_softsrc() <= 480){ //缓存池数据快用完 iis数据跟不上 人为加点
            resample_flg = 1;
        }else if(cbuf_total_samples_get_user_for_softsrc() >= 960){//缓存池数据快爆满 iis数据太快 人为丢点
            resample_flg = 2;
        }else{
            resample_flg = 0;
        }
#endif // IIS_SOFT_RESAMPLES_EN
        void iis_rx_kick_start(void);
        iis_rx_kick_start();// kick music 处理 回调接口iis_rx_callback_procsee()
    }
}

AT(.com_text.iis_ext)
void iis_rx_kick_soft_isr(void)
{
    iis_rx_cfg.soft_isr_kick_flag = 1;
    SWINT();
}

//IIS 接收到的数据 中断处理接口 主要负责把数据搬运到缓存buf并kick 现场处理
AT(.com_text.iis_ext)
void iis_rx_cirbuf_process(void *buf, u32 samples, bool iis_32bit)
{
    //把数据放到缓存池 不在中断中处理
    iis_rx_input_pool((u8*)buf,samples*2,0,NULL);
}

void iis_audio_in_init(void)
{
    //使用单工 iis_cfg.mode = IIS_MASTER_SRCTX时 目前只支持单向默认配置同时需要重定义 bool iis_ext_enable(void) 为true
    printf("\n--->%s\n",__func__);
    memset(&iis_cfg,0x00, sizeof(iis_cfg));
    iis_cfg.mode        = IIS_SLAVE_RAMRX; //IIS_MASTER_RAMRX;//IIS_SLAVE_RAMRX;
    iis_cfg.iomap       = I2S_MAPPING_SEL;
    iis_cfg.bit_mode    = I2S_BIT_MODE;
    iis_cfg.data_mode   = I2S_DATA_MODE;
    iis_cfg.mclk_sel    = I2S_MCLK_SEL;
    iis_cfg.mclk_out_en = IIS_MCLK_OUT_DIS;

    if (iis_cfg.mode & IISCFG_DMA) {
        printf("iis_dma config run\n");
        iis_cfg.dma_cfg.samples = IIS_DMA_SAMPLES;
        iis_cfg.dma_cfg.dmabuf_ptr = iis_dmabuf;
        iis_cfg.dma_cfg.dmabuf_len = IIS_DMABUF_LEN;
        iis_cfg.dma_cfg.iis_isr_rx_callbck = iis_rx_cirbuf_process;  //iis_rx接收完一个DMA后起中断,回调该函数,可以从buf中取出接收到数据
        iis_cfg.dma_cfg.iis_isr_tx_callbck = NULL;  //iis_tx发送完一个DMA后起中断,要求向buf中填入数据,以备下一次发送
    }
    iis_cfg_init(&iis_cfg);
    memset(&iis_dmabuf, 0, sizeof(iis_dmabuf));

    iis_rx_pool_init(WIRELESS_MIC_SAMPLE_RATE_SELECT,WIRELESS_MIC_SAMPLES_SELECT);

    iis_soft_init();
    iis_start();
}

#endif // I2S_RX_AUDIO_EN
